using System;
using System.Data;
using System.Xml;
using System.Runtime.Serialization;
using System.Collections;
using Widgetsphere.Core.Exceptions;
using Widgetsphere.Core.DataAccess;
using ACME.Northwind.Business;
using ACME.Northwind.Business.Objects;
using ACME.Northwind.Business.Rules;
using ACME.Northwind.Business.SelectCommands;
using System.Collections.Generic;

namespace ACME.Northwind.Domain.Objects
{
	/// <summary>
	/// This is an customizable extender for the domain class associated with the 'Supplier' object
	/// </summary>
	[Serializable()]
	partial class DomainSupplier : PersistableDomainObjectBase
	{
		#region Member Variables

		private const string TABLE_NAME = "SupplierCollection";
		internal DomainSupplierCollection ParentCol;

		#endregion

		#region Constructor

		internal DomainSupplier(DataRowBuilder rb) : base(rb) 
		{
			this.ParentCol = ((DomainSupplierCollection)(base.Table));
		}

		#endregion

		#region Properties

		internal SupplierPrimaryKey PrimaryKey
		{
			get { return new SupplierPrimaryKey(this.SupplierId); }
		}

		internal string Address
		{
			get
			{
				try
				{
					if (base[this.ParentCol.AddressColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.AddressColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.AddressColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.AddressColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.Address = value;
				}
			}
		}

		internal string City
		{
			get
			{
				try
				{
					if (base[this.ParentCol.CityColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.CityColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.CityColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.CityColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.City = value;
				}
			}
		}

		internal string CompanyName
		{
			get
			{
				try
				{
					if (base[this.ParentCol.CompanyNameColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.CompanyNameColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  if (value == null) throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_SETNULL);

			  if (!base[this.ParentCol.CompanyNameColumn].Equals(value))
				{
					base[this.ParentCol.CompanyNameColumn] = value;
			  	wasSet = true;
				}

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.CompanyName = value;
				}
			}
		}

		internal string ContactName
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ContactNameColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ContactNameColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ContactNameColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ContactNameColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.ContactName = value;
				}
			}
		}

		internal string ContactTitle
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ContactTitleColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ContactTitleColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ContactTitleColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ContactTitleColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.ContactTitle = value;
				}
			}
		}

		internal string Country
		{
			get
			{
				try
				{
					if (base[this.ParentCol.CountryColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.CountryColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.CountryColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.CountryColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.Country = value;
				}
			}
		}

		internal string Fax
		{
			get
			{
				try
				{
					if (base[this.ParentCol.FaxColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.FaxColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.FaxColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.FaxColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.Fax = value;
				}
			}
		}

		internal string HomePage
		{
			get
			{
				try
				{
					if (base[this.ParentCol.HomePageColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.HomePageColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.HomePageColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.HomePageColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.HomePage = value;
				}
			}
		}

		internal string Phone
		{
			get
			{
				try
				{
					if (base[this.ParentCol.PhoneColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.PhoneColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.PhoneColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.PhoneColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.Phone = value;
				}
			}
		}

		internal string PostalCode
		{
			get
			{
				try
				{
					if (base[this.ParentCol.PostalCodeColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.PostalCodeColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.PostalCodeColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.PostalCodeColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.PostalCode = value;
				}
			}
		}

		internal string Region
		{
			get
			{
				try
				{
					if (base[this.ParentCol.RegionColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.RegionColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.RegionColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.RegionColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					SupplierCollection list = (SupplierCollection)this.ParentCol.SubDomain[Collections.SupplierCollection];
					Supplier item = list.GetItemByPK(this.SupplierId);
					if (item != null) item.Region = value;
				}
			}
		}

		internal int SupplierId
		{
			get
			{
				try
				{
					return ((int)(base[this.ParentCol.SupplierIdColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
		}

		internal virtual BusinessObjectList<Product> ProductList
		{
			get
			{
				BusinessObjectList<Product> associatedProductList = null;
				//if (associatedProductList == null)
				//{
					associatedProductList = new BusinessObjectList<Product>();
					foreach (DomainProduct Product in base.GetChildRows(ParentCol.SupplierProductRelation))
					{
						if (Product.RowState != DataRowState.Deleted)
							associatedProductList.Add(new Product(Product));
					}
					associatedProductList.ObjectAdded += new BusinessObjectEventHandler(AssociatedProductList_ObjectAdded);
					associatedProductList.ObjectRemoved += new BusinessObjectEventHandler(AssociatedProductList_ObjectRemoved);
				//}
				return associatedProductList;
			}
		}

		#endregion

		#region Collection Operation Methods

		/// <summary>
		/// Serves as a hash function for this particular type.
		/// </summary>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (obj == null) return false;
			if (obj.GetType() != this.GetType()) return false;

			if ((this.RowState == DataRowState.Deleted) ||
				(((DataRow)obj).RowState == DataRowState.Deleted) ||
				(this.RowState == DataRowState.Detached) ||
				(((DataRow)obj).RowState == DataRowState.Detached))
				return false;

			return ((DomainSupplier)obj).PrimaryKey.Equals(this.PrimaryKey);
		}

		public override void Persist()
		{
			DomainHelper.PersistDomainObject(this, this.ParentCol.SubDomain, Collections.SupplierCollection, this.ParentCol.Modifier);
		}

		public override void Remove()
		{
			this.ParentCol.RemoveSupplier(this);
		}

		#endregion

		#region Relationship Methods
		private void AssociatedProductList_ObjectAdded(object sender, Widgetsphere.Core.EventArgs.BusinessObjectEventArgs e)
		{
			DomainProduct addedItem = (DomainProduct)e.BusinessObject.WrappedClass;
			DomainProductCollection existingProductCollection = (DomainProductCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.ProductCollection);
			bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
			this.ParentCol.SubDomain.EnforceConstraints = false;
			if(addedItem.ParentCol != existingProductCollection)
			{
				this.ParentCol.SubDomain.Merge(new DataRow[] { addedItem } , false, MissingSchemaAction.Error);
				addedItem = existingProductCollection.GetProduct(addedItem.ProductId);
				e.BusinessObject.WrappedClass = addedItem;
			}
			addedItem.SetParentRow(this,this.ParentCol.SupplierProductRelation);
			this.ParentCol.SubDomain.EnforceConstraints = oldEc;
		}

		private void AssociatedProductList_ObjectRemoved(object sender, Widgetsphere.Core.EventArgs.BusinessObjectEventArgs e)
		{
			DomainProduct removedItem = (DomainProduct)e.BusinessObject.WrappedClass;
			bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
			this.ParentCol.SubDomain.EnforceConstraints = false;
			removedItem.SupplierId = null;
			this.ParentCol.SubDomain.EnforceConstraints = oldEc;
		}

		internal virtual void ReleaseNonIdentifyingRelationships()
		{
			this.ProductList.Clear();
		}

		#endregion
	}
}
